home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGSCAL / INLINE.LZH / UNPARS.INC < prev   
Text File  |  1986-10-06  |  7KB  |  318 lines

  1.                        {UnPars.inc}
  2. (*********  Source code Copyright 1986, by L. David Baldwin   *********)
  3.  
  4. type
  5.   symb = (nul,ident4,ident2,identunk,bytesy,wordsy,lparn,rparn);
  6. var
  7.   sy  : symb;
  8.  
  9. {-------------DefaultExtension}
  10. PROCEDURE DefaultExtension(extension:filestring;VAR infile,name :filestring);
  11. {Given a filename, infile, add a default extension if none exists. Return
  12.  also the name without any extension.}
  13. var
  14.  I,J : Integer;
  15.  temp : filestring;
  16. begin
  17. I:=Pos('..',infile);
  18. if I=0 then
  19.   temp:=infile
  20. else
  21.   begin   {a pathname starting with ..}
  22.   temp:=Copy(infile,I+2,64);
  23.   I:=I+1;
  24.   end;
  25. J:=Pos('.',temp);
  26. if J=0 then
  27.   begin
  28.   name := infile;
  29.   infile:=infile+'.'+extension;
  30.   end
  31. else name:=Copy(infile,1,I+J-1);
  32. end;
  33.  
  34. {-------------Getch}
  35. PROCEDURE Getch;
  36. {Return next char in Uch and lch with Uch in upper case. Ignore comments}
  37. var comment : boolean;
  38.   PROCEDURE GetchBasic; {read a character and a character pair}
  39.   begin
  40.   if chi<=ord(st[0]) then
  41.     begin  {NOTE: pair has the same address as lch}
  42.     move(st[chi], pair, 2);
  43.     if lch=chr(tab) then lch:=' ';
  44.     Uch := upcase(lch);
  45.     chi := chi+1;
  46.     end
  47.   else
  48.     if not eof(inf) then
  49.       begin
  50.       readln(inf,st);
  51.       st:=st+' ';  {EOL is equivalent to space}
  52.       chi:=1;
  53.       Getch;
  54.       end
  55.     else
  56.       begin
  57.       eofinf:=true;
  58.       if comment then
  59.         begin
  60.         writeln('Open Comment at End of Input File');
  61.         halt(1);
  62.         end;
  63.       end;
  64.   end;
  65.  
  66. begin  {Getch}
  67. if uch<>' ' then
  68.   symname:=symname+uch;  {build up a phrase with old character}
  69. repeat
  70.   if eofinf then
  71.     begin WriteLn('Unexpected End of Input File'); Halt(1) end;
  72.   comment:=false;
  73.   getchbasic;
  74.   if (uch='{') or (pair='(*') then
  75.     begin
  76.     comment:=true;
  77.     if uch='{' then repeat getchbasic; until uch='}'
  78.     else
  79.       begin
  80.       repeat getchbasic; until pair='*)';
  81.       getchbasic;  {pass by the '*'}
  82.       end;
  83.     end;
  84. until not comment;
  85. end;
  86.  
  87. {-------------SkipSpaces}
  88. PROCEDURE SkipSpaces;
  89. begin
  90. while (Uch=' ') or (Uch=chr(tab)) do
  91.   Getch;
  92. end;
  93.  
  94. {-------------GetDec}
  95. FUNCTION GetDec(var v :integer): boolean ;
  96. const
  97.   ssize = 8;
  98. var
  99.   s        : string[ssize];
  100.   getd     : boolean;
  101.   code     : integer;
  102. begin
  103. getd := false;
  104. s := '';
  105. while (Uch>='0') and (Uch<='9') do
  106.   begin
  107.   getd := true;
  108.   if ord(s[0])<ssize
  109.     then s := s+Uch;
  110.   Getch;
  111.   end;
  112. if getd then
  113.     begin
  114.     val(s,v,code);
  115.     if code<>0
  116.       then error(chi,'Bad Number Format');
  117.     end;
  118. GetDec := getd;
  119. end;
  120.  
  121. {-------------GetHex}
  122. FUNCTION GetHex(var h :integer): boolean;
  123. var
  124.   digit   : integer;     {check for '$' before the call}
  125. begin
  126. h := 0;
  127. GetHex := false;
  128. while (Uch in ['A'..'F','0'..'9']) do
  129.   begin
  130.   GetHex := true;
  131.   if (Uch>='A')
  132.     then digit := ord(Uch)-ord('A')+10
  133.     else digit := ord(Uch)-ord('0');
  134.   if h>=$1000
  135.     then error(chi,'Overflow');
  136.   h := (h shl 4)+digit;
  137.   Getch;
  138.   end;
  139. end;
  140.  
  141. {-------------GetNumber}
  142. FUNCTION GetNumber(var n :integer): boolean;
  143. {get a number and return it in n}
  144. begin
  145. skipspaces;
  146. n := 0;
  147. if Uch='$'
  148.   then
  149.     begin        {a hex number}
  150.     Getch;
  151.     if not GetHex(n)
  152.       then error(chi, 'Hex Number Exp');
  153.     GetNumber := true;
  154.     end
  155.   else
  156.     begin        {maybe a decimal number}
  157.     GetNumber := getdec(n);
  158.     end;
  159. end;
  160.  
  161. {-------------GetExpr}
  162. FUNCTION GetExpr(var rslt :integer): boolean;
  163. var
  164.   rs1,rs2 : integer;
  165.   pos,neg,GE : boolean;
  166. begin
  167. GE := false;
  168. SkipSpaces;
  169. neg := Uch='-';
  170. pos := Uch='+';
  171. if pos or neg
  172.   then Getch;
  173. if GetNumber(rs1)
  174.   then
  175.     begin
  176.     GE := true;
  177.     if neg
  178.       then rs1 := -rs1;
  179.     skipspaces;
  180.     if (Uch='+') or (Uch='-') then
  181.       if GetExpr(rs2) then
  182.         rs1 := rs1+rs2      {GetExpr will take care of sign}
  183.       else GE:=false;
  184.     rslt := rs1;
  185.     end;
  186. skipspaces;
  187. GetExpr:=GE and ((uch='/') or (uch=')'));  {must terminate in '/' or ')'}
  188. end;
  189.  
  190. {-------------Gettoken}
  191. PROCEDURE Gettoken;
  192. const
  193.   tokenchars : set of char = ['A'..'Z','0'..'9','_'];
  194.   startchars : set of char = ['A'..'Z','_'];
  195. begin
  196. while not (Uch in startchars) and not eofinf do getch;
  197. token[0] := #0;
  198. if not eofinf then
  199.     while Uch in tokenchars do
  200.       begin
  201.       if ord(token[0])<tokenleng
  202.         then token := token+Uch;
  203.       Getch;
  204.       end;
  205. end;
  206.  
  207. {-------------next}
  208. PROCEDURE next;
  209. var c : char;
  210.  
  211.   FUNCTION GetExprX(var N : integer; var C : char): boolean;
  212.   begin
  213.   C:=Uch;
  214.   if (uch='>') or (uch='<') then getch;
  215.   GetExprX:=GetExpr(N);
  216.   end;
  217.  
  218. begin
  219. sy := nul;
  220. Repeat
  221.   SkipSpaces;
  222.   symname[0]:=#0;     {build up a phrase which may be needed later}
  223.   if bytepending then
  224.     begin
  225.     nvalue:=pendingbyte;
  226.     bytepending:=false;
  227.     sy:=bytesy;
  228.     end
  229.   else if uch='(' then begin sy:=lparn; getch; end
  230.   else if uch=')' then begin sy:=rparn; getch; end
  231.   else if uch='/' then error(chi+2, 'Syntax')
  232.   else if GetExprX(nvalue,c) then
  233.     begin
  234.     if c='<' then sy:=bytesy
  235.       else if c='>' then sy:=wordsy
  236.       else if nvalue and $ff00 = 0 then sy := bytesy
  237.       else sy:=wordsy;
  238.     if uch='/' then getch;
  239.     end
  240.   else
  241.     begin  {it's a symbolic phrase}
  242.     while (uch<>'/') and (uch<>')') do getch;  {finish reading the phrase}
  243.     if uch='/' then
  244.       begin
  245.       getch;  {pass the '/' by}
  246.       symname[0]:=pred(symname[0]); {but remove it from phrase}
  247.       end;
  248.     if (pos('>',symname)>0) or (pos('*',symname)>0) then
  249.       sy:=ident4
  250.     else if pos('<',symname)>0 then sy:=ident2
  251.     else sy:=identunk;    {unknown size}
  252.     end;
  253.   if sy=nul then getch;
  254. until sy<>nul;
  255. end;
  256.  
  257. {-------------getbyte}
  258. FUNCTION getbyte(var p :packet; phraseok : boolean): boolean;
  259. var result : boolean;
  260. begin
  261. result:=true;
  262. with p do
  263.   begin
  264.   dispsize:=bytesize;  phrase:=false;
  265.   if (sy=ident2) or (sy=identunk) then
  266.     begin
  267.     if not phraseok then result:=false
  268.     else
  269.       begin
  270.       phrase:=true;
  271.       if sy=identunk then insert('<',symname,1);
  272.       s:=symname;  {the phrase}
  273.       end;
  274.     end
  275.   else if sy=bytesy then value:=lo(nvalue)
  276.   else if sy=wordsy then
  277.     begin
  278.     value:=lo(nvalue);
  279.     bytepending:=true;
  280.     pendingbyte:=Hi(nvalue);
  281.     end
  282.   else result:=false;
  283.   if result then
  284.     begin
  285.     PC:=PC+1;
  286.     next;
  287.     end;
  288.   getbyte:=result;
  289.   end;
  290. end;
  291.  
  292. {-------------getword}
  293. PROCEDURE getword(var p :packet);
  294. var H,L : packet;
  295.   PROCEDURE WordErr;
  296.   begin error(chi,'Word or two bytes exp'); PC:=PC+2; next; end;
  297. begin
  298. with p do
  299.   begin
  300.   dispsize:=wordsize; phrase:=false;
  301.   if (sy=ident4) or (sy=identunk) then
  302.     begin
  303.     if sy=identunk then insert('>',symname,1);
  304.     phrase:=true; s:=symname;
  305.     PC:=PC+2;  next;
  306.     end
  307.   else if sy=ident2 then worderr
  308.   else if sy=wordsy then
  309.     begin value:=nvalue; PC:=PC+2;  next; end
  310.   else if getbyte(L,not PhraseOk) then
  311.     begin
  312.     if not getbyte(H, not PhraseOk) then numbyteerr;
  313.     value:=H.value shl 8 +L.value;
  314.     end
  315.   else WordErr;
  316.   end;
  317. end;
  318.